package shoot;

import java.awt.Graphics;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.awt.image.BufferedImage;
import java.nio.channels.NonReadableChannelException;
import java.util.Arrays;
import java.util.Random;
import java.util.Timer;
import java.util.TimerTask;

import javax.swing.JFrame;
import javax.swing.JPanel;


/**
 * 主类
 */
public class World extends JPanel {
    /**
     * 定义常量
     */
    public static final int WIDTH=400;
    public static final int HEIGHT=700;

    public static final int START=0;
    public static final int RUNNING=1;
    public static final int PAUSE=2;
    public static final int GAMEOVER=3;
    public int status=START;
    
    private static BufferedImage images_start;
    private static BufferedImage images_pause;
    private static BufferedImage images_over;
    static {
    	images_start=FlyingObject.loadImage("start.png");
    	images_pause=FlyingObject.loadImage("pause.png");
    	images_over=FlyingObject.loadImage("gameover.png");
    }
    		
    
    
    /**
     * 实例化对象
     */
    private Sky sky=new Sky();
    private HeroAirPlane hero = new HeroAirPlane();
    private FlyingObject[] enemys= {};
    private Bullet[] bullets = {};
    
    /**
     * 按一定的比例，随机生成飞行物,
     * @return
     */
    public FlyingObject nextOne() {
    	Random random=new Random();
    	int type=random.nextInt(19);
    	if (type<10) {
			return new Bee();
		}else if (type<12) {
			return new SmallAirPlane();
		}else {
			return new BigAirPlane();
		}
    }
    
    /**
     * 飞行物入场
     */
    int enemyIndex=0;
    public void enemysAction() {
    	enemyIndex++;
    	if(enemyIndex%40==0) {
    		//生成飞行物
    		FlyingObject object= nextOne();
    		//将飞行物数组扩容
    		enemys=Arrays.copyOf(enemys,enemys.length+1);
    		//在新数组中进行填充
    		enemys[enemys.length-1]=object; 		
    	}
    }
    
    /**
     * 子弹入场
     */
    int bulletIndex=0;
    public void bulltetAction() {
		bulletIndex++;
		if(bulletIndex%30==0) {
			//生成子弹
			Bullet[] bs=hero.shoot();
			//扩容
			bullets=Arrays.copyOf(bullets, bullets.length+bs.length);
			//在原数组的基础上进行填充
			System.arraycopy(bs, 0,bullets,bullets.length-bs.length, bs.length);
		}
	}
    
    /**
     * 飞行物移动
     */
    public void stepAction() {
		sky.step();
		for (int i = 0; i < bullets.length; i++) {
			bullets[i].step();
		}
		for (int i = 0; i < enemys.length; i++) {
			enemys[i].step();
		}
	}
    
    public void goOutAction() {
    	int index=0;
    	FlyingObject[] enemyLives=new FlyingObject[enemys.length];
		for (int i = 0; i < enemys.length; i++) {
			if (!enemys[i].goOut() && !enemys[i].isRemove()) {
				enemyLives[index]=enemys[i];
				index++;
			}
		}
		enemys=Arrays.copyOf(enemyLives, index);
		
		index=0;
		Bullet[] bulletLives=new Bullet[bullets.length];
		for (int i = 0; i < bullets.length; i++) {
			if(!bullets[i].goOut()) {
				bulletLives[index]=bullets[i];
				index++;
			}
		}
		bullets=Arrays.copyOf(bulletLives, index);
	}
    
    /**
     * 英雄机和飞行物碰撞
     */
    public void heroBangAction() {
    	//飞行物碰撞
		for (int i = 0; i < enemys.length; i++) {
			FlyingObject e=enemys[i];
			if (e.isLife() && hero.isLife() && e.hit(hero)) {
				e.goDie();
				hero.delLife();
				hero.clearDoubleFire();
			}
		}
	}

    /**
     * 子弹和飞行物碰撞
     */
    int score=0;
    public void bulletBangAction() {
		for (int i = 0; i < bullets.length; i++) {
			Bullet b=bullets[i];
			for (int j = 0; j < enemys.length; j++) {
				FlyingObject e =enemys[j];
				if (b.isLife() && e.isLife() && e.hit(b)) {
					b.goDie();
					e.goDie();
					//判断消灭的是大敌机还是小敌机
					if (e instanceof Enemy) {
						Enemy ene=(Enemy)e;
					    score += ene.getScore();
					}
					
					if (e instanceof Award) {
						Award aw =(Award)e;
						int type=aw.getAwardType();
						switch (type) {
						case Award.DOUBLEFIRE:
							hero.addDoubleFire();
							break;
						case Award.LIFES:
							hero.addLife();
							break;
						default:
							break;
						}
 					}
				}
			}
		}
	}
    
    /**
     * 检查游戏是否结束
     */
    public void checkGameOver() {
		if (hero.getLife()<=0) {
			status=GAMEOVER;
		}
	}
    
    
    /**
     * 重载 画对象
     */
    @Override
    public void paint(Graphics g) {
    	// TODO Auto-generated method stub
    	sky.paintObject(g);
    	hero.paintObject(g);
    
    	for (int i = 0; i < enemys.length; i++) {
			enemys[i].paintObject(g);
		}
    	for (int i = 0; i < bullets.length; i++) {
			bullets[i].paintObject(g);
		}
    	
    	g.drawString("得分值："+score, 10, 10);
    	g.drawString("生命值："+hero.getLife(), 10, 25);
    	g.drawString("火力值："+hero.getDoubleFire(), 10, 40);
    	
    	switch (status) {
		case START:
			g.drawImage(images_start, 0, 0, null);
			break;
		case PAUSE:
			g.drawImage(images_pause, 0, 0, null);
			break;
		case GAMEOVER:
			g.drawImage(images_over, 0, 0, null);
			break;
		default:
			break;
		}
    }
    
    public void action() {	
    	MouseAdapter adapter=new MouseAdapter() {
    		@Override
    		public void mouseMoved(MouseEvent e) {
    			// TODO Auto-generated method stub
    			hero.moveTo(e.getX(), e.getY());
    		}
    		
    		@Override
    		public void mouseClicked(MouseEvent e) {
    			// TODO Auto-generated method stub
    			switch (status) {
				case START:
					status=RUNNING;
					break;
				case RUNNING:
					status=PAUSE;
					break;
				case PAUSE:
					status=RUNNING;
					break;
				case GAMEOVER:
					status=START;
					score=0;
					hero=new HeroAirPlane();
					sky=new Sky();
					enemys=new  FlyingObject[0];
					bullets=new Bullet[0];
					break;
				default:
					break;
				}
    		}
    	};
    	//监听鼠标事件
    	addMouseListener(adapter);
    	addMouseMotionListener(adapter);
    	//定时器
    	Timer timer=new Timer();
    	int intevl=10;
    	timer.schedule(new TimerTask() {
			@Override
			public void run() {
				// TODO Auto-generated method stub
				if (status==RUNNING) {
					enemysAction();
					bulltetAction();
					stepAction();
					goOutAction();
					heroBangAction();
					bulletBangAction();
					checkGameOver();
				}
				//重画对象
				repaint();
			}
		}, intevl,intevl);
    	
    }

    public static void main(String[] args) {
    	JFrame jFrame=new JFrame();
    	World world=new World();
    	world.action();
    	jFrame.add(world);
    	jFrame.setSize(World.WIDTH,World.HEIGHT);
    	jFrame.setVisible(true);
    	jFrame.setLocationRelativeTo(null);
    }
}
